class LabelEditorPureCanvas implements LabelEditorPureCanvas_Other, LabelEditorPureCanvas_SplitTxtByMaxWidth {
    private canvas: HTMLCanvasElement;
    public ctx: CanvasRenderingContext2D;
    private userImageLib: { [name: string]: HTMLImageElement } = {};
    constructor() {

    }
    public templateToPngBase64(tpl: TPLData, imgType: any, boardmodel: any) {
        let backGroundColor = "#ffffff";
        if (boardmodel?.attr?.LabelBackgroundColor != undefined) {
            if (boardmodel.attr.LabelBackgroundColor.length > 2) {
                backGroundColor = boardmodel.attr.LabelBackgroundColor;
            }
        }
        let invertColorArea: number[];
        if (boardmodel?.attr?.LabelInverseColor != undefined) {
            if (Array.isArray(boardmodel.attr.LabelInverseColor)) {
                if (boardmodel.attr.LabelInverseColor.length == 4) {
                    invertColorArea = boardmodel.attr.LabelInverseColor;
                }
            }
        }

        let paperWidth: number = tpl.attr.width;
        let paperHeight: number = tpl.attr.height;
        if (this.canvas == undefined) {
            /**创建画布，获取画布上下文。-------------------------------- */
            this.canvas = document.createElement("canvas");
            this.canvas.width = paperWidth;
            this.canvas.height = paperHeight;
            this.ctx = this.canvas.getContext("2d");
        }

        return new Promise<string>(async (resolve, reject) => {
            this.ctx.clearRect(0, 0, paperWidth, paperHeight);
            /**填充白色的背景。------------------------------------------- */
            this.ctx.fillStyle = backGroundColor;
            this.ctx.fillRect(0, 0, paperWidth, paperHeight);
            if (invertColorArea != undefined) {
                this.ctx.fillStyle = "#000000";
                this.ctx.fillRect(invertColorArea[0], invertColorArea[1], invertColorArea[2], invertColorArea[3]);
            }
            for (let i = 0; i < tpl.children.length; i++) {
                /**开始绘制上面的文字。----------------------------------- */
                if (tpl.children[i].type == "TextBlock") {
                    let txt: string = tpl.children[i].value;
                    txt = this.replaceAll(txt, "undefined", "");
                    if (txt.trim().length == 0) {
                        continue;
                    }
                    let txtAttr: any = tpl.children[i].attr;
                    this.ctx.save();

                    this.ctx.fillStyle = this.GetTextColor(txtAttr, invertColorArea, tpl.children[i])
                    let fontWeight: string = txtAttr.textStyle["font-weight"];
                    if (fontWeight == "none") {
                        fontWeight = "normal";
                    }
                    let xieTi: string = txtAttr.textStyle["font-style"];
                    if (xieTi == "normal" || xieTi == "none") {
                        xieTi = "";
                    }
                    let fontFamliy: string = "微软雅黑";
                    if (txtAttr.textStyle["font-family"] != undefined) {
                        fontFamliy = txtAttr.textStyle["font-family"];
                    }
                    this.ctx.font = xieTi + " " + fontWeight + " " + txtAttr.textStyle["font-size"] + " " + fontFamliy;
                    let fontSizeNum: number = parseFloat(txtAttr.textStyle["font-size"]);
                    let wordYPos: number = txtAttr.top + txtAttr.height;
                    if (txtAttr["vertical-align"] == "middle") {
                        this.ctx.textBaseline = 'middle';
                        wordYPos = txtAttr.top + txtAttr.height / 2;
                    } else if (txtAttr["vertical-align"] == "top") {
                        this.ctx.textBaseline = 'top';
                        wordYPos = txtAttr.top;
                    } else if (txtAttr["vertical-align"] == "bottom") {
                        this.ctx.textBaseline = 'bottom';
                        wordYPos = txtAttr.top + txtAttr.height;
                    }

                    let wordXPos: number = txtAttr.left;
                    if (txtAttr["text-align"] == "right") {
                        this.ctx.textAlign = "right";
                        wordXPos = txtAttr.left + txtAttr.width;
                    }
                    let txtList: string[] = txt.split("\n");
                    /**再次检查换行。--------------------------------------------------- */
                    let txtMaxWidth: number = txtAttr.width;

                    let newTxtList: string[] = [];
                    for (let j = 0; j < txtList.length; j++) {
                        if (this.ctx.measureText(txtList[j]).width < txtMaxWidth) {
                            newTxtList.push(txtList[j])
                        } else {
                            newTxtList.push(...this.SplitTxtByMaxWidth(txtList[j], txtMaxWidth));
                        }
                    }
                    for (let j = 0; j < newTxtList.length; j++) {
                        this.ctx.fillText(newTxtList[j], wordXPos, wordYPos + fontSizeNum * j);
                    }

                    this.ctx.restore();
                }
                /**绘制板件分布图。----------------------------------------- */
                else if (tpl.children[i].type == "ImageBlock") {
                    let imageTop: number = tpl.children[i].attr.top;
                    let imageLeft: number = tpl.children[i].attr.left;
                    let imageWidth: number = tpl.children[i].attr.width;
                    let imageHeight: number = tpl.children[i].attr.height;
                    let imageHref: any = tpl.children[i].href;
                    if (imageHref.canvas == undefined) {
                        /**如果是用户自己从外部插入的图片。---------------------------- */
                        if (typeof imageHref == "string") {
                            let userImageNode: HTMLImageElement;
                            let idName: string = "userImage" + imageHref.length;
                            if (this.userImageLib[idName] != undefined) {
                                userImageNode = this.userImageLib[idName];
                            } else {
                                userImageNode = await this.LoadImageByUrl(imageHref);
                                this.userImageLib[idName] = userImageNode;
                            }
                            this.ctx.drawImage(userImageNode, imageLeft, imageTop, imageWidth, imageHeight);
                        }
                        continue;
                    }
                    this.ctx.save()
                    if (tpl.children[i].value.indexOf("[$预览图左右镜像]") != -1) {
                        this.ctx.translate(imageWidth + imageLeft, imageTop);
                        this.ctx.scale(-1, 1);
                        this.ctx.drawImage(imageHref.canvas, 0, 0, imageWidth, imageHeight);
                    } else if (tpl.children[i].value.indexOf("[$预览图上下镜像]") != -1) {
                        this.ctx.translate(imageLeft, imageTop + imageHeight);
                        this.ctx.scale(1, -1);
                        this.ctx.drawImage(imageHref.canvas, 0, 0, imageWidth, imageHeight);
                    } else if (tpl.children[i].value.indexOf("[$预览图旋转180]") != -1) {
                        this.ctx.translate(imageLeft + imageWidth, imageTop + imageHeight);
                        this.ctx.scale(-1, -1);
                        this.ctx.drawImage(imageHref.canvas, 0, 0, imageWidth, imageHeight);
                    } else {
                        this.ctx.drawImage(imageHref.canvas, imageLeft, imageTop, imageWidth, imageHeight);
                    }
                    imageHref.jcanvas.clear();
                    this.ctx.restore();
                }
                /**绘制二维码。---------------------------------------------- */
                else if (tpl.children[i].type == "CodeBlock") {
                    let codeTop: number = tpl.children[i].attr.top;
                    let codeLeft: number = tpl.children[i].attr.left;
                    let codeWidth: number = tpl.children[i].attr.width;
                    let codeHeight: number = tpl.children[i].attr.height;
                    let codeValue: string = tpl.children[i].value;

                    if (tpl.children[i].type2 == "QRCode") {
                        let divElemnt: HTMLDivElement = document.createElement('div');
                        let qrCode = new QRCode(divElemnt, {
                            text: codeValue,
                            width: codeWidth,
                            height: codeHeight,
                            colorDark: "#000000",
                            colorLight: "#ffffff",
                            correctLevel: QRCode.CorrectLevel.L,
                            typeNumber: 4
                        });
                        let codeImageNode = divElemnt.getElementsByTagName("img")[0];
                        codeImageNode = await this.waitForImageLoaded(codeImageNode);
                        this.ctx.drawImage(codeImageNode, codeLeft, codeTop, codeWidth, codeHeight);
                        qrCode.clear();
                    } else if (tpl.children[i].type2 == "DMCode") {
                        let dmCodeCanvas: HTMLCanvasElement = document.createElement("canvas");
                        dmCodeCanvas.width = codeWidth;
                        dmCodeCanvas.height = codeHeight;
                        bwipjs.toCanvas(dmCodeCanvas, { "bcid": "datamatrix", "text": codeValue });
                        this.ctx.drawImage(dmCodeCanvas, codeLeft, codeTop, codeWidth, codeHeight);
                    } else if (tpl.children[i].type2 == "BarCode") {
                        let barCodeCanvas: HTMLCanvasElement = document.createElement("canvas");
                        barCodeCanvas.width = codeWidth;
                        barCodeCanvas.height = codeHeight;
                        bwipjs.toCanvas(barCodeCanvas, { "bcid": "code128", "text": codeValue });
                        this.ctx.drawImage(barCodeCanvas, codeLeft, codeTop, codeWidth, codeHeight);
                    }
                }
            }
            let returnBase64: string = this.canvas.toDataURL('image/jpeg');
            returnBase64 = returnBase64.split(',')[1];
            /**避免同时绘图，会把进程卡死。---------------------------------- */
            requestAnimationFrame(() => {
                resolve(returnBase64);
            })
        });
    }
    public replaceAll(str: string, target: string, replace: string): string {
        let raRegExp: RegExp = new RegExp(target.toString().replace(/([\(\)\[\]\{\}\^\$\+\-\*\?\.\"\'\|\/\\])/g, "\\$1"), "ig");
        str = str.toString().replace(raRegExp, replace.toString());
        return str;
    }
    public Destroy() {
        this.userImageLib = {};
    }
    LoadImageByUrl = LabelEditorPureCanvas_Other.prototype.LoadImageByUrl;
    waitForImageLoaded = LabelEditorPureCanvas_Other.prototype.waitForImageLoaded;
    GetTextColor = LabelEditorPureCanvas_Other.prototype.GetTextColor;
    HasInverset = LabelEditorPureCanvas_Other.prototype.HasInverset;
    SplitTxtByMaxWidth = LabelEditorPureCanvas_SplitTxtByMaxWidth.prototype.SplitTxtByMaxWidth;
}